
import { useRouter } from 'vue-router';
class CarManager {
  constructor (map) {
    this.map = map;
    this.carList = [];
    const onTick = () => {
      this.carList.forEach(item => {
        const position = this.getSmoothPosition(item);
        if (position) {
          const heading = item.properties.heading;
          item.position = position;
          item.orientation = Cesium.Transforms.headingPitchRollQuaternion(
            position,
            new Cesium.HeadingPitchRoll(
              Cesium.Math.toRadians(heading),
              Cesium.Math.toRadians(0),
              Cesium.Math.toRadians(0)
            )
          );
        }
      });
    };
    this.map.clock.onTick.addEventListener(onTick);
    const router = useRouter();
    const handler = new Cesium.ScreenSpaceEventHandler(map.scene.canvas);
    handler.setInputAction((evt) => {
      const pick = map.scene.pick(evt.position);
      if (Cesium.defined(pick) && pick.id) {
        const entity = pick.id;
        const index = this.carList.findIndex(item => item.id === entity.id);
        if (index !== -1) {
          router.push({
            path: '/Car',
            query: {
              id: entity.id
            }
          });
        }
      }
    }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
  }

  /**
   * 获取平滑坐标
   */
  getSmoothPosition (car) {
    const properties = car.properties;
    if (!properties.dTime || properties.dTime <= 0) return;

    // 渲染的时间间隔
    const iTime = Date.now() - properties.endTime; // 有一个周期的延迟，当前时刻开始的时间是上个周期结束的时间
    // this.dTime 后台数据的时间间隔
    const percent = iTime / properties.dTime;
    if (percent <= 1) {
      // 渲染的时间比较快  需要进行插值  达到平滑过渡效果
      const rx = properties.startPoint._value.x + properties.dx * percent;
      const ry = properties.startPoint._value.y + properties.dy * percent;
      const rz = properties.startPoint._value.z + properties.dz * percent;
      return new Cesium.Cartesian3(rx, ry, rz);
    }
  }

  /**
   * 添加车辆
   */
  addCar (item) {
    console.log('添加car: ' + item['vin']);
    const lng = parseFloat(item.longitude);
    const lat = parseFloat(item.latitude);
    const alt = parseFloat(item.altitude ? item.altitude : 0);
    const position = Cesium.Cartesian3.fromDegrees(lng, lat, alt);
    const heading = parseFloat(item.heading);
    const car = {
      id: item.vin,
      position: position,
      orientation: Cesium.Transforms.headingPitchRollQuaternion(
        position,
        new Cesium.HeadingPitchRoll(
          Cesium.Math.toRadians(heading),
          Cesium.Math.toRadians(0),
          Cesium.Math.toRadians(0)
        )
      ),
      model: {
        uri: './data/car.gltf',
        minimumPixelSize: 64
        // scale: new Cesium.CallbackProperty(() => {
        //   if (!this.map) {
        //     return 1.0;
        //   }
        //   const height = this.map.camera.positionCartographic.height;
        //   if (height > 3000) {
        //     return 20.0;
        //   } else if (height > 3000) {
        //     return 15.0;
        //   } else if (height > 2000) {
        //     return 10.0;
        //   } else if (height > 1000) {
        //     return 5.0;
        //   } else if (height > 500) {
        //     return 3.0;
        //   } else {
        //     return 1.0;
        //   }
        // }, false)
      },
      label: {
        text: `ID:${item.vin}`,
        font: 'normal 15px MicroSoft YaHei', // 字体样式
        fillColor: Cesium.Color.fromCssColorString('#9BD5FF'), // 字体颜色
        backgroundColor:
          Cesium.Color.fromCssColorString('#091C2E').withAlpha(0.2), // 背景颜色
        showBackground: true, // 是否显示背景颜色
        verticalOrigin: Cesium.VerticalOrigin.CENTER, // 垂直位置
        horizontalOrigin: Cesium.HorizontalOrigin.LEFT, // 水平位置
        pixelOffset: new Cesium.Cartesian2(20, 0),
        disableDepthTestDistance: 50000
      },
      properties: {
        startPoint: position,
        endPoint: position,
        startTime: Date.now(),
        endTime: Date.now()
      }
    };
    this.carList.push(this.map.entities.add(car));
  }

  /**
   * 更新车辆信息
   */
  updateCar (index, item) {
    console.log('更新car: ' + item['vin']);
    const car = this.carList[index];
    const lng = parseFloat(item.longitude);
    const lat = parseFloat(item.latitude);
    const alt = parseFloat(item.altitude ? item.altitude : 0);
    const position = car.properties.endPoint._value;
    const endPosition = Cesium.Cartesian3.fromDegrees(lng, lat, alt);
    const heading = parseFloat(item.heading) + 90;
    const endTime = car.properties.endTime;
    car.properties = {
      startPoint: position,
      endPoint: endPosition,
      startTime: endTime,
      endTime: Date.now(),
      // 经纬度高度变换分量，用于做平滑处理
      dx: endPosition.x - position.x,
      dy: endPosition.y - position.y,
      dz: endPosition.z - position.z,
      // 时间间隔属性，此处可为外部函数调用时间间隔
      dTime: Date.now() - endTime,
      // 旋转角度
      heading: heading
    };
  }

  removeAllCar () {
    this.map.entities.removeAll();
    this.carList = [];
  }

  removeCar (id) {
    const index = this.carList.findIndex(item => item.id === id);
    if (index !== -1) {
      const car = this.carList[index];
      this.map.entities.remove(car);
      this.carList.splice(index, 1);
    }
  }

  /**
   * 依据数据源更新车辆信息
   * @param { Array } dataArr 数据源
   */
  update (dataArr) {
    dataArr.forEach(item => {
      const index = this.carList.findIndex(ele => ele.id === item.vin);
      if (index === -1) {
        this.addCar(item);
      } else {
        this.updateCar(index, item);
      }
    });
    // this.carList.forEach(item => {
    //   const index = dataArr.findIndex(ele => ele.vin === item.id);
    //   if (index === -1) {
    //     this.removeCar(item.id);
    //   }
    // });
  }

  /**
   * 获取地图范围
   */
  static getRange (map) {
    const extend = map.camera.computeViewRectangle();
    const coordToLonlat = (x, y) => {
      const { camera, scene } = map;
      const d2 = new Cesium.Cartesian2(x, y);
      const ellipsoid = scene.globe.ellipsoid;
      // 2D转3D世界坐标
      const d3 = camera.pickEllipsoid(d2, ellipsoid);
      // 3D世界坐标转弧度
      const upperLeftCartographic =
        scene.globe.ellipsoid.cartesianToCartographic(d3);
      // 弧度转经纬度
      const lng = Cesium.Math.toDegrees(upperLeftCartographic.longitude);
      const lat = Cesium.Math.toDegrees(upperLeftCartographic.latitude);
      return { lng, lat };
    };
    if (extend) {
      const west = Cesium.Math.toDegrees(extend.west);
      const south = Cesium.Math.toDegrees(extend.south);
      const east = Cesium.Math.toDegrees(extend.east);
      const north = Cesium.Math.toDegrees(extend.north);
      return [
        west,
        south,
        east,
        north
      ];
    } else {
      const canvas = map.scene.canvas;
      const upperLeftLonLat = coordToLonlat(0, 0);
      const lowerRightLonLat = coordToLonlat(
        canvas.clientWidth,
        canvas.clientHeight
      );
      const xmin = upperLeftLonLat.lng;
      const ymax = upperLeftLonLat.lat;
      const xmax = lowerRightLonLat.lng;
      const ymin = lowerRightLonLat.lat;
      return [
        xmin, ymin, xmax, ymax
      ];
    }
  }
}

export default CarManager;
